/*
 *  GELine3d.h
 *  TestGE
 *
 *  Created by Quoc Dung Chu on 16/07/11.
 *  Copyright 2011 Paris 6. All rights reserved.
 *
 */



#ifndef GE_LINE_3D_H
#define GE_LINE_3D_H


#import <math.h>
#include "GEPoint3d.h"
#include "GEVector3d.h"
namespace game_engine
{
	namespace vect_math
	{
		
		template <class T> class GEPoint3d;
		template <class T>
		class GELine3d  {
		public:
			
			GEPoint3d<T> start;
			GEPoint3d<T> end;
			

			GELine3d():start(0,0,0),end(1,1,1){}
			
			GELine3d(T xa, T ya, T za, T xb, T yb, T zb) : start(xa,ya,za), end(xb, yb , zb){}
			
			GELine3d(const GEPoint3d<T>& start, const GEPoint3d<T>& end): start(start), end(end) {}
			
			T length() const
			{
				return start.distance(end);
			}
			
			GEPoint3d<T> middle() 
			{
				return (start + end ) / (T)2;
			}
			
			GEVector3d<T> vector()
			{
				return end - start;
			}
			
			GEPoint3d<T> min()
			{
				return GEPoint3d<T>(Min(start.X,end.X),Min(start.Y,end.Y),Min(start.Z,end.Z));
			}
			
			GEPoint3d<T> max()
			{
				return GEPoint3d<T>(Max(start.X,end.X),Max(start.Y,end.Y),Max(start.Z,end.Z));
			}
			
		
			
			// return true if this line is intersected with other line in plan (XY)
			bool isIntersectedXY ( GELine3d<T>& other )
			{
				GEPoint3d<T> minThis = this->min();
				GEPoint3d<T> maxThis = this->max();
				GEPoint3d<T> minOther = other.min();
				GEPoint3d<T> maxOther = other.max();
				
				if (   minThis.X > maxOther.X || minOther.X > maxThis.X 
					|| minThis.Y > maxOther.Y || minOther.Y > maxThis.Y) 
				{	
					return false;
				}
				
				if(start.X == end.X || other.start.X == other.end.X ) return true;
				
				bool startIsAboveOther = start.isAboveXY(other);
				bool endIsAboveOther = end.isAboveXY(other);
				if ( (startIsAboveOther && !endIsAboveOther) 
					|| ( !startIsAboveOther && endIsAboveOther)) return true; 
				
				return false;
			}
		};
		
		
		
	}
}

#endif